iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
自我挑戰組

模仿知名網站的外觀系列 第 8

【Day8】模仿知名網站的外觀 Instagram(8) 編寫Comment區塊

  • 分享至 

  • xImage
  •  

在打造Instagram Clone系列的第八篇文章中,我們將完善Comment區塊。

整個Comment大致上可以分成兩部分左邊顯示圖片的區塊,右邊則是顯示評論的區塊。

我們開始寫圖片的區塊,來到CommentModal.jsx。

import { Modal, ModalBody, ModalContent, ModalOverlay } from "@chakra-ui/react";
import React from "react";

const CommentModal = ({ onClose, isOpen }) => {
	return (
		<div>
			<Modal size={"4xl"} onClose={onClose} isOpen={true} isCentered>
				<ModalOverlay />
				<ModalContent>
					<ModalBody>
						<div className="flex h-[75vh]">
							<div className="w-[45%] flex flex-col justify-center">
								<img
									className="max-h-full w-full"
									src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
									alt=""
								/>
							</div>
							<div className="border w-[55%]"></div>
						</div>
					</ModalBody>
				</ModalContent>
			</Modal>
		</div>
	);
};

export default CommentModal;

目前的設計長這樣

Untitled

接下來寫右邊的部分,最上面的是一個頭像和用戶名稱。將CommentModal.jsx的ModalBody內的程式碼做修改。

<div className="flex h-[75vh]">
	<div className="w-[45%] flex flex-col justify-center">
		<img
			className="max-h-full w-full"
			src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
			alt=""
		/>
	</div>
	<div className="border w-[55%]">
		<div className="flex items-center">
			<div>
				<img
					className="w-9 h-9 rounded-full"
					src="https://images.pexels.com/photos/17857033/pexels-photo-17857033.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
					alt=""
				/>
			</div>
			<div className="ml-2">
				<p>username</p>
			</div>
		</div>
	</div>
</div>

結果如下

Untitled

添加icon

import { BsThreeDots } from "react-icons/bs";

修改部分程式碼

<div className="flex h-[75vh]">
	<div className="w-[45%] flex flex-col justify-center">
		<img
			className="max-h-full w-full"
			src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
			alt=""
		/>
	</div>
	<div className="w-[55%] pl-10">
		<div className="flex justify-between items-center py-5">
			<div className="flex items-center">
				<div>
					<img
						className="w-9 h-9 rounded-full"
						src="https://images.pexels.com/photos/17857033/pexels-photo-17857033.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
						alt=""
					/>
				</div>
				<div className="ml-2">
					<p>username</p>
				</div>
			</div>

			<BsThreeDots />
		</div>
	</div>
</div>

完成右側一小部分

Untitled

在Comment資料夾下,新增CommentCard.jsx,我們先做出一個評論樣板。

import React from "react";

const CommentCard = () => {
	return (
		<div>
			<div>
				<div>
					<div>
						<img
							className="w-9 h-9 rounded-full"
							src="https://images.pexels.com/photos/12286255/pexels-photo-12286255.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
							alt=""
						/>
					</div>
					<div>
						<p>
							<span>username</span>
							<span>awesome</span>
						</p>
					</div>
				</div>
			</div>
		</div>
	);
};

export default CommentCard;

修改CommentModal.jsx,顯示我們的評論樣板。

<div className="flex h-[75vh]">
	<div className="w-[45%] flex flex-col justify-center">
		<img
			className="max-h-full w-full"
			src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
			alt=""
		/>
	</div>
	<div className="w-[55%] pl-10">
		<div className="flex justify-between items-center py-5">
			<div className="flex items-center">
				<div>
					<img
						className="w-9 h-9 rounded-full"
						src="https://images.pexels.com/photos/17857033/pexels-photo-17857033.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
						alt=""
					/>
				</div>
				<div className="ml-2">
					<p>username</p>
				</div>
			</div>

			<BsThreeDots />
		</div>
		<hr />
		<div>
			{[1, 1, 1].map(() => <CommentCard />)}
		</div>
	</div>
</div>

修改後的模樣

Untitled

在CommentCard.jsx的return區塊,添加CSS和一些元素,代表多久前的留言、有多少人按喜歡。

<div>
	<div>
		<div className="flex items-center">
			<div>
				<img
					className="w-9 h-9 rounded-full"
					src="https://images.pexels.com/photos/12286255/pexels-photo-12286255.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
					alt=""
				/>
			</div>
			<div className="ml-3">
				<p>
					<span className="font-semibold">username</span>
					<span className="ml-2">awesome</span>
				</p>
				<div className="flex items-center space-x-3 text-xs opacity-60 pt-2">
					<span>10h</span>
					<span>21 likes</span>
				</div>
			</div>
		</div>
	</div>
</div>

提供修改後的結果作參考

Untitled

接下來在版面上增加愛心,以及完成按愛心和取消的功能,繼續修改CommentCard.jsx。

import React, { useState } from "react";
import { AiFillHeart, AiOutlineHeart } from "react-icons/ai";

const CommentCard = () => {
	const [isCommentLike, setIsCommentLike] = useState();

	const handleLikeComment = () => {
		setIsCommentLike(!isCommentLike);
	};

	return (
		<div>
			<div className="flex items-center justify-between py-5">
				<div className="flex items-center">
					<div>
						<img
							className="w-9 h-9 rounded-full"
							src="https://images.pexels.com/photos/12286255/pexels-photo-12286255.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
							alt=""
						/>
					</div>
					<div className="ml-3">
						<p>
							<span className="font-semibold">username</span>
							<span className="ml-2">awesome</span>
						</p>
						<div className="flex items-center space-x-3 text-xs opacity-60 pt-2">
							<span>10h</span>
							<span>21 likes</span>
						</div>
					</div>
				</div>
				{isCommentLike ? (
					<AiFillHeart
						onClick={() => handleLikeComment()}
						className="text-xs hover:opacity-50 cursor-pointer text-red-600"
					/>
				) : (
					<AiOutlineHeart
						onClick={() => handleLikeComment()}
						className="text-xs hover:opacity-50 cursor-pointer"
					/>
				)}
			</div>
		</div>
	);
};

export default CommentCard;

按下愛心看能不能成功變化。

Untitled

至此我們已經完成2/3的版面了,剩下底部的區塊,這部分和之前寫過的部分很像,可以直接複製過來,就在PostCard.jsx。

<div className="flex justify-between items-center w-full px-5 py-4">
	<div className="flex items-center space-x-2">
		{isPostLiked ? (
			<AiFillHeart
				className="text-2xl hover:opacity-50 cursor-pointer text-red-600"
				onClick={() => handlePostLike()}
			/>
		) : (
			<AiOutlineHeart
				className="text-2xl hover:opacity-50 cursor-pointer"
				onClick={() => handlePostLike()}
			/>
		)}

		<FaRegComment className="text-xl hover:opacity-50 cursor-pointer" />
		<IoPaperPlaneOutline className="text-xl hover:opacity-50 cursor-pointer" />
	</div>

	<div className="cursor-pointer">
		{isPostSaved ? (
			<BsBookmarkFill
				onClick={() => handlePostSave()}
				className="text-xl hover:opacity-50 cursor-pointer"
			/>
		) : (
			<BsBookmark
				onClick={() => handlePostSave()}
				className="text-xl hover:opacity-50 cursor-pointer"
			/>
		)}
	</div>
</div>

複製貼上到CommentModal.jsx,刪除複製過來的第一行的px-5。import用到的icon,更改CommentModal的參數,最後的程式碼如下:

import { Modal, ModalBody, ModalContent, ModalOverlay } from "@chakra-ui/react";
import React from "react";
import CommentCard from "./CommentCard";
import { BsBookmark, BsBookmarkFill, BsThreeDots } from "react-icons/bs";
import { AiFillHeart, AiOutlineHeart } from "react-icons/ai";
import { FaRegComment } from "react-icons/fa";
import { IoPaperPlaneOutline } from "react-icons/io5";

const CommentModal = ({
	onClose,
	isOpen,
	isPostLiked,
	isPostSaved,
	handlePostLike,
	handlePostSave,
}) => {
	return (
		<div>
			<Modal size={"4xl"} onClose={onClose} isOpen={true} isCentered>
				<ModalOverlay />
				<ModalContent>
					<ModalBody>
						<div className="flex h-[75vh]">
							<div className="w-[45%] flex flex-col justify-center">
								<img
									className="max-h-full w-full"
									src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
									alt=""
								/>
							</div>
							<div className="w-[55%] pl-10">
								<div className="flex justify-between items-center py-5">
									<div className="flex items-center">
										<div>
											<img
												className="w-9 h-9 rounded-full"
												src="https://images.pexels.com/photos/17857033/pexels-photo-17857033.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
												alt=""
											/>
										</div>
										<div className="ml-2">
											<p>username</p>
										</div>
									</div>

									<BsThreeDots />
								</div>
								<hr />
								<div>
									{[1, 1, 1].map(() => (
										<CommentCard />
									))}
								</div>

								<div className="flex justify-between items-center w-full py-4">
									<div className="flex items-center space-x-2">
										{isPostLiked ? (
											<AiFillHeart
												className="text-2xl hover:opacity-50 cursor-pointer text-red-600"
												onClick={() => handlePostLike()}
											/>
										) : (
											<AiOutlineHeart
												className="text-2xl hover:opacity-50 cursor-pointer"
												onClick={() => handlePostLike()}
											/>
										)}

										<FaRegComment className="text-xl hover:opacity-50 cursor-pointer" />
										<IoPaperPlaneOutline className="text-xl hover:opacity-50 cursor-pointer" />
									</div>

									<div className="cursor-pointer">
										{isPostSaved ? (
											<BsBookmarkFill
												onClick={() => handlePostSave()}
												className="text-xl hover:opacity-50 cursor-pointer"
											/>
										) : (
											<BsBookmark
												onClick={() => handlePostSave()}
												className="text-xl hover:opacity-50 cursor-pointer"
											/>
										)}
									</div>
								</div>
							</div>
						</div>
					</ModalBody>
				</ModalContent>
			</Modal>
		</div>
	);
};

export default CommentModal;

多出一行按鈕,目前的按鈕還沒有作用。

Untitled


上一篇
【Day7】模仿知名網站的外觀 Instagram(7) 編寫Instagram首頁-2與Chakra UI
下一篇
【Day9】模仿知名網站的外觀 Instagram(9) 編寫Comment區塊-2
系列文
模仿知名網站的外觀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言